/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.view.gl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.model.SelectItem;
import org.primefaces.context.RequestContext;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import src.domain.gl.*;
import src.services.gl.FstmtModel;
import src.services.gl.GlaccntConverter;
import src.services.system.BranchModel;
import src.util.Constanta;
import src.util.Messager;
import src.util.Utils;

/**
 *
 * @author Lalugina
 */
@ManagedBean
@SessionScoped
public class FstmtBean implements Serializable  {

    /**
     * Creates a new instance of FstmtBean
     */
    private List<SelectItem> avblType, avblFormat, avblBranch;
    private List<SelectItem> avblTotals, avblPeriod;
    private List<Fstmt> fstmts;

    private Fstmt selectedData, unsaveData;
    private Fstmtline fstmtline;
    
    private Glaccnt glfrom = new Glaccnt();
    private Glaccnt glto = new Glaccnt();
    private List<Glaccnt> avblGL; 
    private List<FstmtReport> reports; 
    private Integer month, year, branchId, fstmtId; 
    private String value01Text, value02Text, value03Text, format; 
    
    
    private boolean editMode = false, showDlg=false, updatePanel=false, success=false, compareCol=false;
            
    public FstmtBean() {
        initFilter();
        this.avblType = Constanta.getFstmtType();
        this.avblFormat = Constanta.getFstmtFormat();
        this.avblPeriod = src.util.Utils.getMonths();
        this.avblBranch = new BranchModel().listAll();
        this.avblTotals = new ArrayList<>();
        
        this.fstmts = new FstmtModel().findAll(null);
        this.selectedData = null;
        this.unsaveData = null;
        this.reports = new ArrayList<>();
        
        avblGL = GlaccntConverter.glaccountDB;
    }

    private void initFilter () {
        Calendar cal = Calendar.getInstance();
        
        month = cal.get(Calendar.MONTH)+1;
        year = cal.get(Calendar.YEAR);
    }
    
    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public Integer getBranchId() {
        return branchId;
    }

    public void setBranchId(Integer branchId) {
        this.branchId = branchId;
    }

    public Integer getMonth() {
        return month;
    }

    public void setMonth(Integer month) {
        this.month = month;
    }

    public Integer getYear() {
        return year;
    }

    public void setYear(Integer year) {
        this.year = year;
    }

    public Fstmt getSelectedData() {
        return selectedData;
    }

    public void setSelectedData(Fstmt selectedData) {
        this.selectedData = selectedData;
    }

    public Fstmt getUnsaveData() {
        return unsaveData;
    }

    public void setUnsaveData(Fstmt unsaveData) {
        this.unsaveData = unsaveData;
    }
    
    public List<Fstmt> getFstmts() {
        return fstmts;
    }

    public Fstmtline getFstmtline() {
        return fstmtline;
    }

    public void setFstmtline(Fstmtline fstmtline) {
        this.fstmtline = fstmtline;
    }

    public List<Glaccnt> getAvblGL() {
        return avblGL;
    }

    public void setAvblGL(List<Glaccnt> avblGL) {
        this.avblGL = avblGL;
    }

    public Glaccnt getGlfrom() {
        return glfrom;
    }

    public void setGlfrom(Glaccnt glfrom) {
        this.glfrom = glfrom;
    }

    public Glaccnt getGlto() {
        return glto;
    }

    public void setGlto(Glaccnt glto) {
        this.glto = glto;
    }

    public List<SelectItem> getAvblType() {
        return avblType;
    }

    public List<SelectItem> getAvblFormat() {
        return avblFormat;
    }

    public List<SelectItem> getAvblTotals() {
        return avblTotals;
    }

    public List<SelectItem> getAvblBranch() {
        return avblBranch;
    }
    
    public boolean isEditMode() {
        return editMode;
    }

    public boolean isShowDlg() {
        return showDlg;
    }

    public void setShowDlg(boolean showDlg) {
        this.showDlg = showDlg;
    }

    public boolean isUpdatePanel() {
        return updatePanel;
    }

    public void setUpdatePanel(boolean updatePanel) {
        this.updatePanel = updatePanel;
    }
    
    private void loadTotals() {
        avblTotals.clear();
        for(Fstmtline ln : unsaveData.getFstmtlines()) {  
            if(ln.getLineType() != null && (ln.getLineType().equals(Constanta.FSTMT_TOTAL) || ln.getLineType().equals(Constanta.FSTMT_TOTAL_REVENUE))) {
                avblTotals.add(new SelectItem(ln.getId().getSeq(), ln.getLineDescription()));
            }
        }  
    }
   
    public void initForm() {
        this.fstmtline = null;
        this.updatePanel=false;
    }
        
    public void handleClose() {
        this.showDlg=false;
        this.selectedData = null;
        this.unsaveData = null;
        this.editMode = true;     
    }
        
    public List<Glaccnt> completeGL(String query) {  
        List<Glaccnt> suggestions = new ArrayList<>();  
        String q = query.trim();
            
        for(Glaccnt gl : avblGL) {  
            if(gl.getAccountNo().startsWith(q) || gl.getAccountName().toLowerCase().startsWith(q.toLowerCase()))  
                suggestions.add(gl);  
        }  
        return suggestions;  
    }  
    
    public void newData() {  
        initForm();
        this.editMode = false;
        this.selectedData = null;
        this.unsaveData = new Fstmt();
        addLine();
    }
    
    public void openData() {
        initForm();
        this.editMode = true;
        this.unsaveData = Fstmt.clone(selectedData);
        
        if (unsaveData.getFstmtlines().isEmpty()) {
            prepareLine();
            this.unsaveData.getFstmtlines().add(fstmtline);
        }    
        
        for (int i=0; i < unsaveData.getFstmtlines().size(); i++) {
            unsaveData.getFstmtlines().get(i).setFstmtIdSeq(i+1);
        }
        
        addLine();
        loadTotals();
    }
        
    public void prepareLine() {
        Integer seq = 0;
         if (!unsaveData.getFstmtlines().isEmpty()) 
            seq = unsaveData.getFstmtlines().get(unsaveData.getFstmtlines().size()-1).getId().getSeq()+1;
                
        fstmtline = new Fstmtline(unsaveData.getFstmtId(), seq);
        updatePanel = false;
    }
    
    public void addLine() {
        prepareLine();
        unsaveData.getFstmtlines().add(fstmtline);
    }
    
    public void inserLine() {
        setUpdatePanel(false);
        int i=0;
        int count=unsaveData.getFstmtlines().size();
        int lineIdx=count; 
        boolean found=false;
        while (i < count && !found) {
            found = unsaveData.getFstmtlines().get(i).getId().getSeq() == fstmtline.getId().getSeq() ? true:false;
            i++;
            lineIdx = i;
        }
        
        prepareLine();
        if (lineIdx > count) lineIdx--;
        this.unsaveData.getFstmtlines().add(lineIdx, fstmtline);
        fstmtline=null;
    }
    
    public void addLineGL() {
        setUpdatePanel(false);
        if (fstmtline.getLineType().equals(Constanta.FSTMT_DETAIL)) {
            
            Integer seq = 1;
            if (!fstmtline.getFstmtaccs().isEmpty()) 
                seq = fstmtline.getFstmtaccs().get(fstmtline.getFstmtaccs().size()-1).getId().getSeq()+1;
         
            Fstmtacc fstmtacc = new Fstmtacc(fstmtline.getId().getFstmtId(), fstmtline.getId().getSeq(), seq);
            fstmtline.getFstmtaccs().add(fstmtacc);
        }
    }
    
    public void addLineTotal() {
        setUpdatePanel(false);
        if (fstmtline.getLineType().equals(Constanta.FSTMT_DETAIL)) {
            
            Integer seq = 1;
            if (!fstmtline.getFstmttots().isEmpty()) 
                seq = fstmtline.getFstmttots().get(fstmtline.getFstmttots().size()-1).getId().getSeq()+1;
            
            Fstmttot fstmttot = new Fstmttot(fstmtline.getId().getFstmtId(), fstmtline.getId().getSeq(), seq);
            fstmtline.getFstmttots().add(fstmttot);
        }
    }
    
    public void rowEditedLine(RowEditEvent event) {
        setUpdatePanel(false);
        loadTotals();
    }
    
    public void rowEditedGL(RowEditEvent event) {
        Fstmtacc fstmtacc = (Fstmtacc) event.getObject(); 
        fstmtacc.setAccountNoFrom(glfrom.getAccountNo()); 
        fstmtacc.setAccountNoTo(glto.getAccountNo()); 
        setUpdatePanel(false);
    }
    
    public void rowEdited(RowEditEvent event) {
        setUpdatePanel(false);
    }
    
    public void showDialog(String value) {
        value+=".show();";
        RequestContext.getCurrentInstance().execute(value);
    }
    
    public void handleRemoveLine(int seq){
        
        int i=0;
        int lineIdx=-1;        
        int count = unsaveData.getFstmtlines().size();
        boolean found=false;
        while (i < count && !found) {
            lineIdx = i;
            found = unsaveData.getFstmtlines().get(i).getId().getSeq() == seq ? true:false;
            i++;
        }
        
        if (lineIdx > -1) unsaveData.getFstmtlines().remove(lineIdx);
        if (unsaveData.getFstmtlines().isEmpty()) {
            prepareLine();
            unsaveData.getFstmtlines().add(fstmtline);
        }
                
        this.updatePanel=true;
    }
    
    public void handleRemoveGL(Integer seq){
        int i=0;
        int lineIdx=-1;        
        int count = fstmtline.getFstmtaccs().size();
        boolean found=false;
        while (i < count && !found) {
            lineIdx = i;
            found = fstmtline.getFstmtaccs().get(i).getId().getSeq() == seq ? true:false;
            i++;
        }
        if (lineIdx > -1) fstmtline.getFstmtaccs().remove(lineIdx);
        this.updatePanel= true;
    }
    
    public void handleRemoveTotal(Integer seq){
        int i=0;
        int lineIdx=-1;        
        int count = fstmtline.getFstmttots().size();
        boolean found=false;
        while (i < count && !found) {
            lineIdx = i;
            found = fstmtline.getFstmttots().get(i).getId().getSeq() == seq ? true:false;
            i++;
        }
        if (lineIdx > -1) fstmtline.getFstmttots().remove(lineIdx);
        this.updatePanel= true;
    }
    
    private void removeNullRows() {
        for(int i = 0; i<unsaveData.getFstmtlines().size(); i++){
            Fstmtline v_line = unsaveData.getFstmtlines().get(i);
            
            //remove akun
            for(int j=0; j< v_line.getFstmtaccs().size(); j++) {
                String value = v_line.getFstmtaccs().get(j).getAccountNoFrom();
                if(value==null) {
                    v_line.getFstmtaccs().remove(j);
                    j--;
                }
            }
            
            //remove total
            for(int j=0; j< v_line.getFstmttots().size(); j++) {
                Integer value = v_line.getFstmttots().get(j).getFstmtIdSeq();
                if(value==null) {
                    v_line.getFstmttots().remove(j);
                    j--;
                }
            }
            
            String value = unsaveData.getFstmtlines().get(i).getLineType();
            String invalidDeskripsi = unsaveData.getFstmtlines().get(i).getLineDescription();
            if(value==null || (value.equals(Constanta.FSTMT_HEADER) && invalidDeskripsi.equals(""))) {
                unsaveData.getFstmtlines().remove(i);
                i--;
            }
        }
    }
    
    public void createReport(boolean isNeraca) {
        initForm();
        this.editMode = false;
        this.selectedData = null;
        this.selectedData = null;
        if (isNeraca) this.unsaveData = new FstmtModel().generateNeraca();
        else this.unsaveData = new FstmtModel().generateLabaRugi();
        loadTotals();
    }   
        
    public void save() {
        RequestContext context = RequestContext.getCurrentInstance();
        removeNullRows();
        
        success = new FstmtModel().trySave(unsaveData);
        if (success==true) {
            if (this.editMode==false) this.fstmts.add(unsaveData);
            else {
                int i = fstmts.indexOf(selectedData);
                if (i <= fstmts.size()) fstmts.set(i, Fstmt.clone(unsaveData));
            }
            editMode = true;
            
        } else {
            if (this.editMode==false) unsaveData.setFstmtId(null);
        }
        
        Messager.showSaveUpdateStatus(success);        
        context.addCallbackParam("success", success);  
    }
    
    public void delete() {
        RequestContext context = RequestContext.getCurrentInstance();  
                
        success = new FstmtModel().deleteData(this.selectedData);
        
        if (success) {
            this.fstmts.remove(this.selectedData);
            this.selectedData = null;
        } 
        Messager.showDeleteStatusConstaint(success);  
        context.addCallbackParam("success", success);  
    }

    public String selectItemValueOf(List<SelectItem> avblList, Object id) {
        return (String) Utils.selectItemValueOf(avblList, id);
    }
    
    public void onStateSelect(SelectEvent event) {  
    //    unsaveData = (Fstmt) event.getObject();
    }
        
    public void onLineSelect(SelectEvent event) {
     //   Fstmtline cekData = (Fstmtline) event.getObject();
    //    System.out.println(cekData.getLineDescription());
    
    }
    
    public String rowClass(String val) {
        String rowclass = null;
        switch (val) {
            case Constanta.FSTMT_HEADER: rowclass = "gridGroup"; break;
            case Constanta.FSTMT_TOTAL: rowclass = "gridGroup"; break;
            case Constanta.FSTMT_DETAIL: rowclass = null; break;
            case Constanta.FSTMT_DETAIL_REVENUE: rowclass = null; break;
            case Constanta.FSTMT_SPARATOR: rowclass = "gridSparator"; break;
        }
        
        return rowclass;
    }
    
    public void loadReport() {
        this.reports = new FstmtModel().loadData(fstmtId, branchId, month, year);
        value01Text= selectItemValueOf(avblPeriod, month) +" "+ year; 
        value02Text=""; 
        value03Text="Change"; 
        compareCol=false;
        
        Integer lastMonth = month -1;
        Integer lastYear = year;
        
        if (lastMonth==0) {
            lastMonth = 12;
            lastYear = year-1;
        }
                
        switch (format) {
            case Constanta.FSTMT_FORMAT_NET_CHANGE_SIMPLE : 
                value03Text="";
                break;
                
            case Constanta.FSTMT_FORMAT_NET_CHANGE_COMPARE_MONTH : 
                value02Text= selectItemValueOf(avblPeriod, lastMonth) +" "+ lastYear; 
                compareCol=true;
                break;
                
            case Constanta.FSTMT_FORMAT_NET_CHANGE_COMPARE_YEAR : 
                value02Text= selectItemValueOf(avblPeriod, month) +" "+ (year-1);
                compareCol=true;
                break; 
                
            case Constanta.FSTMT_FORMAT_BALANCE_SIMPLE : 
                value03Text="";
                break;
                
            case Constanta.FSTMT_FORMAT_BALANCE_COMPARE_YEAR : 
                value02Text= selectItemValueOf(avblPeriod, month) +" "+ (year-1);
                compareCol=true;
                break;     
        } 
    }

    public List<FstmtReport> getReports() {
        return reports;
    }

    public String getValue01Text() {
        return value01Text;
    }

    public String getValue02Text() {
        return value02Text;
    }

    public String getValue03Text() {
        return value03Text;
    }

    public boolean isCompareCol() {
        return compareCol;
    }
    
    public void cekReport() {
       this.format = selectedData.getFormat();
       this.fstmtId = selectedData.getFstmtId();
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public Integer getFstmtId() {
        return fstmtId;
    }

    public void setFstmtId(Integer fstmtId) {
        this.fstmtId = fstmtId;
    }
    
    
    
}
